﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xunit;
using Moq;

namespace MvcWiki.Test.Repository.FileSystem.WikiNamespaceFileSystemRepository
{
    public class GetAllWikiNamespacesFacts
    {
        [Fact]
        public void Call()
        {
            var repositoryFactory = new Mock<MvcWiki.Repository.IWikiRepositoryFactory>();
            var wikiMarkupProvider = new Mock<MvcWiki.Markup.IWikiMarkupProvider>();
            var unitOfWork = new Mock<MvcWiki.Repository.IUnitOfWork>();
            var fileSystem = new Mock<MvcWiki.Repository.FileSystem.IFileSystemWrapper>();
            var wikiNamespaceRepository = new MvcWiki.Repository.FileSystem.WikiNamespaceFileSystemRepository(repositoryFactory.Object, wikiMarkupProvider.Object, unitOfWork.Object, "c:\\path", fileSystem.Object);

            IList<MvcWiki.Model.WikiNamespace> wikiNamespaces = wikiNamespaceRepository.GetAllWikiNamespaces();
        }

        [Fact]
        public void Gets_All_WikiNamespace_Directories()
        {
            var repositoryFactory = new Mock<MvcWiki.Repository.IWikiRepositoryFactory>();
            var wikiMarkupProvider = new Mock<MvcWiki.Markup.IWikiMarkupProvider>();
            var unitOfWork = new Mock<MvcWiki.Repository.IUnitOfWork>();

            var fileSystem = new Mock<MvcWiki.Repository.FileSystem.IFileSystemWrapper>();

            fileSystem.Setup(x => x.GetDirectories("c:\\path", "*---*")).Returns(
                new string[] {
                    "c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1",
                    "c:\\path\\Namespace2---9f878f17-21bb-4fb1-a68e-3cd2c61201c2",
                    "c:\\path\\Namespace3---9f878f17-21bb-4fb1-a68e-3cd2c61201c3",
                }
            );

            fileSystem.Setup(x => x.FileExists("c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1\\wikinamespace.xml")).Returns(true);
            fileSystem.Setup(x => x.FileExists("c:\\path\\Namespace2---9f878f17-21bb-4fb1-a68e-3cd2c61201c2\\wikinamespace.xml")).Returns(true);
            fileSystem.Setup(x => x.FileExists("c:\\path\\Namespace3---9f878f17-21bb-4fb1-a68e-3cd2c61201c3\\wikinamespace.xml")).Returns(true);

            fileSystem.Setup(x => x.ReadFromFile("c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1\\wikinamespace.xml")).Returns("<wikinamespace><wikimarkup>StandardMarkup</wikimarkup></wikinamespace>");
            fileSystem.Setup(x => x.ReadFromFile("c:\\path\\Namespace2---9f878f17-21bb-4fb1-a68e-3cd2c61201c2\\wikinamespace.xml")).Returns("<wikinamespace><wikimarkup>StandardMarkup</wikimarkup></wikinamespace>");
            fileSystem.Setup(x => x.ReadFromFile("c:\\path\\Namespace3---9f878f17-21bb-4fb1-a68e-3cd2c61201c3\\wikinamespace.xml")).Returns("<wikinamespace><wikimarkup>StandardMarkup</wikimarkup></wikinamespace>");

            var wikiNamespaceRepository = new MvcWiki.Repository.FileSystem.WikiNamespaceFileSystemRepository(repositoryFactory.Object, wikiMarkupProvider.Object, unitOfWork.Object, "c:\\path", fileSystem.Object);

            wikiNamespaceRepository.GetAllWikiNamespaces();

            fileSystem.VerifyAll();
        }

        [Fact]
        public void Checks_Whether_WikiNamespace_Xml_Files_Exists()
        {
            var repositoryFactory = new Mock<MvcWiki.Repository.IWikiRepositoryFactory>();
            var wikiMarkupProvider = new Mock<MvcWiki.Markup.IWikiMarkupProvider>();
            var unitOfWork = new Mock<MvcWiki.Repository.IUnitOfWork>();

            var fileSystem = new Mock<MvcWiki.Repository.FileSystem.IFileSystemWrapper>();

            fileSystem.Setup(x => x.GetDirectories("c:\\path", "*---*")).Returns(
                new string[] {
                    "c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1",
                    "c:\\path\\Namespace2---9f878f17-21bb-4fb1-a68e-3cd2c61201c2",
                    "c:\\path\\Namespace3---9f878f17-21bb-4fb1-a68e-3cd2c61201c3",
                }
            );

            fileSystem.Setup(x => x.FileExists("c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1\\wikinamespace.xml")).Returns(true);
            fileSystem.Setup(x => x.FileExists("c:\\path\\Namespace2---9f878f17-21bb-4fb1-a68e-3cd2c61201c2\\wikinamespace.xml")).Returns(true);
            fileSystem.Setup(x => x.FileExists("c:\\path\\Namespace3---9f878f17-21bb-4fb1-a68e-3cd2c61201c3\\wikinamespace.xml")).Returns(true);

            fileSystem.Setup(x => x.ReadFromFile("c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1\\wikinamespace.xml")).Returns("<wikinamespace><wikimarkup>StandardMarkup</wikimarkup></wikinamespace>");
            fileSystem.Setup(x => x.ReadFromFile("c:\\path\\Namespace2---9f878f17-21bb-4fb1-a68e-3cd2c61201c2\\wikinamespace.xml")).Returns("<wikinamespace><wikimarkup>StandardMarkup</wikimarkup></wikinamespace>");
            fileSystem.Setup(x => x.ReadFromFile("c:\\path\\Namespace3---9f878f17-21bb-4fb1-a68e-3cd2c61201c3\\wikinamespace.xml")).Returns("<wikinamespace><wikimarkup>StandardMarkup</wikimarkup></wikinamespace>");

            var wikiNamespaceRepository = new MvcWiki.Repository.FileSystem.WikiNamespaceFileSystemRepository(repositoryFactory.Object, wikiMarkupProvider.Object, unitOfWork.Object, "c:\\path", fileSystem.Object);

            wikiNamespaceRepository.GetAllWikiNamespaces();

            fileSystem.VerifyAll();
        }

        [Fact]
        public void Throws_Exception_If_WikiNamespace_Xml_Files_Does_Not_Exist()
        {
            var repositoryFactory = new Mock<MvcWiki.Repository.IWikiRepositoryFactory>();
            var wikiMarkupProvider = new Mock<MvcWiki.Markup.IWikiMarkupProvider>();
            var unitOfWork = new Mock<MvcWiki.Repository.IUnitOfWork>();

            var fileSystem = new Mock<MvcWiki.Repository.FileSystem.IFileSystemWrapper>();

            fileSystem.Setup(x => x.GetDirectories("c:\\path", "*---*")).Returns(
                new string[] {
                    "c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1",
                    "c:\\path\\Namespace2---9f878f17-21bb-4fb1-a68e-3cd2c61201c2",
                    "c:\\path\\Namespace3---9f878f17-21bb-4fb1-a68e-3cd2c61201c3",
                }
            );

            fileSystem.Setup(x => x.FileExists("c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1\\wikinamespace.xml")).Returns(false);

            var wikiNamespaceRepository = new MvcWiki.Repository.FileSystem.WikiNamespaceFileSystemRepository(repositoryFactory.Object, wikiMarkupProvider.Object, unitOfWork.Object, "c:\\path", fileSystem.Object);

            Assert.Throws<MvcWiki.Exceptions.NamespaceDoesNotExistException>(
                () => wikiNamespaceRepository.GetAllWikiNamespaces());
        }

        [Fact]
        public void Reads_All_WikiNamespace_Xml_Files()
        {
            var repositoryFactory = new Mock<MvcWiki.Repository.IWikiRepositoryFactory>();
            var wikiMarkupProvider = new Mock<MvcWiki.Markup.IWikiMarkupProvider>();
            var unitOfWork = new Mock<MvcWiki.Repository.IUnitOfWork>();

            var fileSystem = new Mock<MvcWiki.Repository.FileSystem.IFileSystemWrapper>();

            fileSystem.Setup(x => x.GetDirectories("c:\\path", "*---*")).Returns(
                new string[] {
                    "c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1",
                    "c:\\path\\Namespace2---9f878f17-21bb-4fb1-a68e-3cd2c61201c2",
                    "c:\\path\\Namespace3---9f878f17-21bb-4fb1-a68e-3cd2c61201c3",
                }
            );

            fileSystem.Setup(x => x.FileExists("c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1\\wikinamespace.xml")).Returns(true);
            fileSystem.Setup(x => x.FileExists("c:\\path\\Namespace2---9f878f17-21bb-4fb1-a68e-3cd2c61201c2\\wikinamespace.xml")).Returns(true);
            fileSystem.Setup(x => x.FileExists("c:\\path\\Namespace3---9f878f17-21bb-4fb1-a68e-3cd2c61201c3\\wikinamespace.xml")).Returns(true);

            fileSystem.Setup(x => x.ReadFromFile("c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1\\wikinamespace.xml")).Returns("<wikinamespace><wikimarkup>StandardMarkup</wikimarkup></wikinamespace>");
            fileSystem.Setup(x => x.ReadFromFile("c:\\path\\Namespace2---9f878f17-21bb-4fb1-a68e-3cd2c61201c2\\wikinamespace.xml")).Returns("<wikinamespace><wikimarkup>StandardMarkup</wikimarkup></wikinamespace>");
            fileSystem.Setup(x => x.ReadFromFile("c:\\path\\Namespace3---9f878f17-21bb-4fb1-a68e-3cd2c61201c3\\wikinamespace.xml")).Returns("<wikinamespace><wikimarkup>StandardMarkup</wikimarkup></wikinamespace>");

            var wikiNamespaceRepository = new MvcWiki.Repository.FileSystem.WikiNamespaceFileSystemRepository(repositoryFactory.Object, wikiMarkupProvider.Object, unitOfWork.Object, "c:\\path", fileSystem.Object);

            wikiNamespaceRepository.GetAllWikiNamespaces();

            fileSystem.VerifyAll();
        }

        [Fact]
        public void Returns_IList_Of_WikiNamespaces()
        {
            var repositoryFactory = new Mock<MvcWiki.Repository.IWikiRepositoryFactory>();
            var wikiMarkupProvider = new Mock<MvcWiki.Markup.IWikiMarkupProvider>();
            var unitOfWork = new Mock<MvcWiki.Repository.IUnitOfWork>();

            var fileSystem = new Mock<MvcWiki.Repository.FileSystem.IFileSystemWrapper>();

            fileSystem.Setup(x => x.GetDirectories("c:\\path", "*---*")).Returns(
                new string[] {
                    "c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1",
                    "c:\\path\\Namespace2---9f878f17-21bb-4fb1-a68e-3cd2c61201c2",
                    "c:\\path\\Namespace3---9f878f17-21bb-4fb1-a68e-3cd2c61201c3",
                }
            );

            fileSystem.Setup(x => x.FileExists("c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1\\wikinamespace.xml")).Returns(true);
            fileSystem.Setup(x => x.FileExists("c:\\path\\Namespace2---9f878f17-21bb-4fb1-a68e-3cd2c61201c2\\wikinamespace.xml")).Returns(true);
            fileSystem.Setup(x => x.FileExists("c:\\path\\Namespace3---9f878f17-21bb-4fb1-a68e-3cd2c61201c3\\wikinamespace.xml")).Returns(true);

            fileSystem.Setup(x => x.ReadFromFile("c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1\\wikinamespace.xml")).Returns("<wikinamespace><wikimarkup>StandardMarkup</wikimarkup></wikinamespace>");
            fileSystem.Setup(x => x.ReadFromFile("c:\\path\\Namespace2---9f878f17-21bb-4fb1-a68e-3cd2c61201c2\\wikinamespace.xml")).Returns("<wikinamespace><wikimarkup>StandardMarkup</wikimarkup></wikinamespace>");
            fileSystem.Setup(x => x.ReadFromFile("c:\\path\\Namespace3---9f878f17-21bb-4fb1-a68e-3cd2c61201c3\\wikinamespace.xml")).Returns("<wikinamespace><wikimarkup>StandardMarkup</wikimarkup></wikinamespace>");

            var wikiNamespaceRepository = new MvcWiki.Repository.FileSystem.WikiNamespaceFileSystemRepository(repositoryFactory.Object, wikiMarkupProvider.Object, unitOfWork.Object, "c:\\path", fileSystem.Object);

            var wikiNamespaces = wikiNamespaceRepository.GetAllWikiNamespaces();

            Assert.Equal<int>(3, wikiNamespaces.Count);

            Assert.Equal<string>("Namespace1", wikiNamespaces[0].Name);
            Assert.Equal<string>("Namespace2", wikiNamespaces[1].Name);
            Assert.Equal<string>("Namespace3", wikiNamespaces[2].Name);
        }

        [Fact]
        public void Returns_IList_Of_WikiNamespaces_With_WikiMarkups()
        {
            var repositoryFactory = new Mock<MvcWiki.Repository.IWikiRepositoryFactory>();

            var wikiMarkup1 = new MvcWiki.Model.WikiMarkup { Name = "StandardMarkup1" };
            var wikiMarkup2 = new MvcWiki.Model.WikiMarkup { Name = "StandardMarkup2" };
            var wikiMarkup3 = new MvcWiki.Model.WikiMarkup { Name = "StandardMarkup3" };

            var wikiMarkupProvider = new Mock<MvcWiki.Markup.IWikiMarkupProvider>();
            wikiMarkupProvider.Setup(x => x.CreateWikiMarkup("StandardMarkup1")).Returns(wikiMarkup1);
            wikiMarkupProvider.Setup(x => x.CreateWikiMarkup("StandardMarkup2")).Returns(wikiMarkup2);
            wikiMarkupProvider.Setup(x => x.CreateWikiMarkup("StandardMarkup3")).Returns(wikiMarkup3);

            var unitOfWork = new Mock<MvcWiki.Repository.IUnitOfWork>();

            var fileSystem = new Mock<MvcWiki.Repository.FileSystem.IFileSystemWrapper>();

            fileSystem.Setup(x => x.GetDirectories("c:\\path", "*---*")).Returns(
                new string[] {
                    "c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1",
                    "c:\\path\\Namespace2---9f878f17-21bb-4fb1-a68e-3cd2c61201c2",
                    "c:\\path\\Namespace3---9f878f17-21bb-4fb1-a68e-3cd2c61201c3",
                }
            );

            fileSystem.Setup(x => x.FileExists("c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1\\wikinamespace.xml")).Returns(true);
            fileSystem.Setup(x => x.FileExists("c:\\path\\Namespace2---9f878f17-21bb-4fb1-a68e-3cd2c61201c2\\wikinamespace.xml")).Returns(true);
            fileSystem.Setup(x => x.FileExists("c:\\path\\Namespace3---9f878f17-21bb-4fb1-a68e-3cd2c61201c3\\wikinamespace.xml")).Returns(true);

            fileSystem.Setup(x => x.ReadFromFile("c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1\\wikinamespace.xml")).Returns("<wikinamespace><wikimarkup>StandardMarkup1</wikimarkup></wikinamespace>");
            fileSystem.Setup(x => x.ReadFromFile("c:\\path\\Namespace2---9f878f17-21bb-4fb1-a68e-3cd2c61201c2\\wikinamespace.xml")).Returns("<wikinamespace><wikimarkup>StandardMarkup2</wikimarkup></wikinamespace>");
            fileSystem.Setup(x => x.ReadFromFile("c:\\path\\Namespace3---9f878f17-21bb-4fb1-a68e-3cd2c61201c3\\wikinamespace.xml")).Returns("<wikinamespace><wikimarkup>StandardMarkup3</wikimarkup></wikinamespace>");

            var wikiNamespaceRepository = new MvcWiki.Repository.FileSystem.WikiNamespaceFileSystemRepository(repositoryFactory.Object, wikiMarkupProvider.Object, unitOfWork.Object, "c:\\path", fileSystem.Object);

            var wikiNamespaces = wikiNamespaceRepository.GetAllWikiNamespaces();

            Assert.Equal<int>(3, wikiNamespaces.Count);

            Assert.Equal<MvcWiki.Model.WikiMarkup>(wikiMarkup1, wikiNamespaces[0].Markup);
            Assert.Equal<MvcWiki.Model.WikiMarkup>(wikiMarkup2, wikiNamespaces[1].Markup);
            Assert.Equal<MvcWiki.Model.WikiMarkup>(wikiMarkup3, wikiNamespaces[2].Markup);
        }

        [Fact]
        public void Calls_IWikiMarkupProvider()
        {
            var repositoryFactory = new Mock<MvcWiki.Repository.IWikiRepositoryFactory>();

            var wikiMarkupProvider = new Mock<MvcWiki.Markup.IWikiMarkupProvider>();
            wikiMarkupProvider.Setup(x => x.CreateWikiMarkup("StandardMarkup1"));
            wikiMarkupProvider.Setup(x => x.CreateWikiMarkup("StandardMarkup2"));
            wikiMarkupProvider.Setup(x => x.CreateWikiMarkup("StandardMarkup3"));

            var unitOfWork = new Mock<MvcWiki.Repository.IUnitOfWork>();

            var fileSystem = new Mock<MvcWiki.Repository.FileSystem.IFileSystemWrapper>();

            fileSystem.Setup(x => x.GetDirectories("c:\\path", "*---*")).Returns(
                new string[] {
                    "c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1",
                    "c:\\path\\Namespace2---9f878f17-21bb-4fb1-a68e-3cd2c61201c2",
                    "c:\\path\\Namespace3---9f878f17-21bb-4fb1-a68e-3cd2c61201c3",
                }
            );

            fileSystem.Setup(x => x.FileExists("c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1\\wikinamespace.xml")).Returns(true);
            fileSystem.Setup(x => x.FileExists("c:\\path\\Namespace2---9f878f17-21bb-4fb1-a68e-3cd2c61201c2\\wikinamespace.xml")).Returns(true);
            fileSystem.Setup(x => x.FileExists("c:\\path\\Namespace3---9f878f17-21bb-4fb1-a68e-3cd2c61201c3\\wikinamespace.xml")).Returns(true);

            fileSystem.Setup(x => x.ReadFromFile("c:\\path\\Namespace1---9f878f17-21bb-4fb1-a68e-3cd2c61201c1\\wikinamespace.xml")).Returns("<wikinamespace><wikimarkup>StandardMarkup1</wikimarkup></wikinamespace>");
            fileSystem.Setup(x => x.ReadFromFile("c:\\path\\Namespace2---9f878f17-21bb-4fb1-a68e-3cd2c61201c2\\wikinamespace.xml")).Returns("<wikinamespace><wikimarkup>StandardMarkup2</wikimarkup></wikinamespace>");
            fileSystem.Setup(x => x.ReadFromFile("c:\\path\\Namespace3---9f878f17-21bb-4fb1-a68e-3cd2c61201c3\\wikinamespace.xml")).Returns("<wikinamespace><wikimarkup>StandardMarkup3</wikimarkup></wikinamespace>");

            var wikiNamespaceRepository = new MvcWiki.Repository.FileSystem.WikiNamespaceFileSystemRepository(repositoryFactory.Object, wikiMarkupProvider.Object, unitOfWork.Object, "c:\\path", fileSystem.Object);

            wikiNamespaceRepository.GetAllWikiNamespaces();

            wikiMarkupProvider.VerifyAll();
        }
    }
}
